package tools

import (
	"errors"
)

type IDPool struct {
	maxID    int    // ID 最大值
	pool     []bool // ID 池，用于记录哪些 ID 已经被分配出去了
	freeList []int  // 可用 ID 列表，记录哪些 ID 是当前可用的
}

func NewIDPool(maxID int) *IDPool {
	pool := make([]bool, maxID+1)
	freeList := make([]int, 0, maxID+1)
	for i := 1; i <= maxID; i++ {
		freeList = append(freeList, i)
	}
	return &IDPool{
		maxID:    maxID,
		pool:     pool,
		freeList: freeList,
	}
}

// Allocate 分配一个 ID
func (p *IDPool) Allocate(id int) error {
	if id < 0 || id > p.maxID {
		return errors.New("ID 超出范围")
	}
	if p.pool[id] {
		return errors.New("ID 已经被分配")
	}
	for i := 0; i < len(p.freeList); i++ {
		if p.freeList[i] == id {
			// 将 ID 从可用列表中移除
			p.freeList = append(p.freeList[:i], p.freeList[i+1:]...)
			break
		}
	}
	p.pool[id] = true
	return nil
}

// Release 回收一个 ID
func (p *IDPool) Release(id int) error {
	if id < 0 || id > p.maxID {
		return errors.New("ID 超出范围")
	}
	if !p.pool[id] {
		return errors.New("ID 未被分配")
	}
	p.pool[id] = false
	// 将 ID 添加到可用列表的末尾
	p.freeList = append(p.freeList, id)
	return nil
}

// Next 获取下一个可用的 ID
func (p *IDPool) Next() (int, error) {
	if len(p.freeList) == 0 {
		return -1, errors.New("没有可用的 ID")
	}
	id := p.freeList[0]
	p.freeList = p.freeList[1:]
	p.pool[id] = true
	return id, nil
}

// Reset reset
func (p *IDPool) Reset() {
	for i := 0; i < len(p.pool); i++ {
		p.pool[i] = false
	}
	p.freeList = p.freeList[:0]
	for i := 1; i <= p.maxID; i++ {
		p.freeList = append(p.freeList, i)
	}
}
